package rpc.remote.transport.socket;

import lombok.extern.slf4j.Slf4j;
import rpc.exceprion.RpcException;
import rpc.extension.ExtensionLoader;
import rpc.remote.dto.Message;
import rpc.remote.dto.RpcRequest;
import rpc.registry.ServiceDiscovery;
import rpc.remote.transport.RpcRequestTransport;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;


/**
 * @ClassName: SocketRpcClient
 * @Description: 使用socket实现两机通信
 * @author: Kowk
 * @since:1.0.0
 */
@Slf4j
public class SocketRpcClient implements RpcRequestTransport {

    private final ServiceDiscovery serviceDiscovery;

    public SocketRpcClient(){
        this.serviceDiscovery = (ServiceDiscovery) ExtensionLoader.getExtensionLoader(ServiceDiscovery.class).getExtension("zk");
    }

    @Override
    public Object sendRpcRequest(RpcRequest request) {
        InetSocketAddress inetSocketAddress = serviceDiscovery.lookupService(request);
        try (Socket socket = new Socket()){
            socket.connect(inetSocketAddress);
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            //通过输出流向服务端发送数据
            objectOutputStream.writeObject(request);
            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            //读取服务端的返回信息
            return objectInputStream.readObject();
        } catch (IOException | ClassNotFoundException e) {
            throw new RpcException("调用失败",e);
        }
    }

    public Object send(Message message, String host, int port){
        //创建socket客户端并指定服务器地址和端口
        try(Socket socket = new Socket(host, port)){
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
            //通过输出流发送信息
            objectOutputStream.writeObject(message);
            //通过输入流获取信息
            ObjectInputStream objectInputStream = new ObjectInputStream(socket.getInputStream());
            return objectInputStream.readObject();
        } catch (IOException | ClassNotFoundException e) {
            log.error("occur exception" + e);
        }
        return null;
    }



}
